#include "serialportThread.h"
#include "mainwindow.h"

SerialportThread* SerialportThread::Instance=0;
extern intListener recfl;
extern QString recvvalue;
extern QString allerror;
extern intListener infochan;

struct order
{
    // 可以添加一个函数来序列化结构体
    QByteArray toByteArray(QString header,QString type,QString len,QString data,QString cd,QString tail) const {
        QString all = header+type+len+data+cd+tail;
        QByteArray byteArray;
        for(int i = 0;i<all.size();i++)
        {
            if(all[i]==' ')
                continue;   //跳过
            int num  = all.mid(i,2).toUInt(nullptr,16);
            i++;
            byteArray.append(num);
        }
        return byteArray;
    }
};

SerialportThread* SerialportThread::getInstance()
{
    if(Instance==0)
        Instance =new SerialportThread();
    return Instance;
}

SerialportThread::SerialportThread(QObject *parent): QSerialPort(parent)
{
    mapGZ = new QMap<QString, QString>();
    mapGZ->insert("0B","EEROM初始化错误");
    mapGZ->insert("0C","温度采集初始化失败");
    mapGZ->insert("0D","温度读取失败");
    mapGZ->insert("0E","A区温度过高");
    mapGZ->insert("0F","B区温度过高");
    mapGZ->insert("10","C区温度过高");
    mapGZ->insert("11","D区温度过高");
    mapGZ->insert("12","E区温度过高");
    mapGZ->insert("13","F区温度过高");
    mapGZ->insert("14","A区温度异常");
    mapGZ->insert("15","B区温度异常");
    mapGZ->insert("16","C区温度异常");
    mapGZ->insert("17","D区温度异常");
    mapGZ->insert("18","E区温度异常");
    mapGZ->insert("19","F区温度异常");
    mapGZ->insert("1A","水泵故障");
    mapGZ->insert("1B","风扇故障");
    mapGZ->insert("1C","仓门打开");
    mapGZ->insert("1D","ad模块通信异常");
    mapGZ->insert("1E","升降电机位置异常");
    mapGZ->insert("1F","开关门电机位置异常");

    connect(this, &SerialportThread::SignalConnectToHost, this, [&](const QString & serialNamePort, QString baud) {

        QSerialPort::BaudRate baudRate;

        if(baud=="115200"){
            baudRate = QSerialPort::Baud115200;
        }
        else if(baud=="4800")
        {
            baudRate = QSerialPort::Baud4800;
        }
        else if(baud=="9600")
        {
            baudRate = QSerialPort::Baud9600;
        }
        else
        {
            return;
        }

        this->setDataBits(QSerialPort::Data8);
        this->setParity(QSerialPort::NoParity);
        this->setStopBits(QSerialPort::OneStop);
        this->setFlowControl(QSerialPort::NoFlowControl);
        this->setPortName(serialNamePort);
        this->setBaudRate(baudRate);
        if(this->open(QIODevice::ReadWrite))
        {
            MainWindow::serialStatus.set(1);//连接成功
            m_bOnLine=true;
        }else{
            MainWindow::serialStatus.set(0);//连接失败
            m_bOnLine=false;
        }
    }, Qt::AutoConnection);

    //收到了TCP服务的数据
    QObject::connect(this, &QIODevice::readyRead, this, [&]() {
        logClient=loghelper::getInstance();
        QByteArray arr = this->readAll();
        QString str;
        for(int c :arr)
        {
            if(c>=0)
            {
                str += QString(" %1").arg(c, 2, 16, QChar('0')).toUpper();
            }
            else
            {
                str += QString(" %1").arg(c+256, 2, 16, QChar('0')).toUpper();
            }
        }
        str= str.simplified();
        logClient->WriteLog("CommLog","接收:\n"+str);
        QStringList list=str.split(" ");
        if(list.length()>12){
            if(list[list.length()-2]=="AA"&& list[list.length()-1]=="55"){
                tempString.append(" "+str);
                recvvalue = str;
                recfl.set(1);

            }else{
                tempString = str;
                return ;
            }
            if(list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]!="3A" )
            {
                if( list[3]=="3C" && list[7]=="07"){
                    if(true)//荧光数据
                    {
                        tempString.clear();
                        QStringList list=str.split(" ");
                        for(int i=12;i<list.length()-4;i+=10){
                            if(i+4>list.length()||i+5>list.length()||i+6>list.length()||i+7>list.length()||
                                    i+8>list.length()||i+9>list.length()){
                                break;
                            }
                            else
                            {
                                QSqlDatabase db = dbHelper::openConnection();
                                QSqlQuery query(db);

                                QString sql=QString("Insert into FluorescenceData values('','%1','%2','%3',"
                                                    "'%4','%5','%6','','','','')").arg(
                                            common->SixteenToTen(list[i]+" "+list[i+1]),
                                        common->SixteenToTen(list[11]),
                                        common->SixteenToTen(list[i+2]+" "+ list[i+3]),
                                        common->SixteenToTen(list[i+4]+" "+ list[i+5]),
                                        common->SixteenToTen(list[i+6]+" "+ list[i+7]),
                                        common->SixteenToTen(list[i+8]+" "+ list[i+9])
                                        );
                                query.exec(sql);
                            }
                        }


                        QSqlDatabase db = dbHelper::openConnection();
                        QSqlQuery query(db);
                        db.transaction();
                        QString sql=QString("update FluorescenceData set SampleId=(select id from sampleInfo s "
                                            "where "
                                            "case "
                                            "when FluorescenceData.PositionNumber %1 = 0 "
                                            "then s.RowNum=7 and s.ColNum=FluorescenceData.PositionNumber/8-1 "
                                            "else "
                                            "s.RowNum = FluorescenceData.PositionNumber %1-1 and s.ColNum = FluorescenceData.PositionNumber/8 "
                                            "end)").arg("%8");
                        query.exec(sql);

                        sql="DELETE FROM FluorescenceData WHERE rowid NOT IN (SELECT MIN(rowid) FROM FluorescenceData GROUP BY positionNumber, CyclesNumber)";
                        query.exec(sql);
                        db.commit();

                    }
                }
                else if (list[3]=="3D" || list[3]=="3C"){
                    if(list[list.length()-2]=="AA"&& list[list.length()-1]=="55"){
                        tempString.append(" "+str);
                        recvvalue = str;
                        recfl.set(1);

                    }else{
                        tempString = str;
                        return ;
                    }
                    tempString.clear();
                }
                else if(list[3]=="38"){
                    if(list[10]=="00" && list[11]=="00"){
                        MainWindow::startExperimentStatus.set(0);
                    }
                    else if(list[10]=="00" &&list[11]=="01"){
                        MainWindow::startExperimentStatus.set(1);
                    }
                    else if(list[10]=="00"&& list[11]=="02"){
                        MainWindow::startExperimentStatus.set(2);
                    }
                }
            }
            if((list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]=="3A")||!tempString.isEmpty())
            {
                if(list.length()== 30 && (list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]=="3A"))//温度数据
                {
                    MainWindow::experimentStep.set(common->SixteenToTen(list[10]).toInt());
                    MainWindow::experimentCircle.set(common->SixteenToTen(list[11]).toInt());

                    QString tempOne =common->SixteenToTen(list[12]+" "+list[13]);
                    MainWindow::tempDataOne=tempOne.toDouble()/100;

                    QString tempTwo=common->SixteenToTen(list[14]+" "+list[15]);
                    MainWindow::tempDataTwo=tempTwo.toDouble()/100;

                    QString tempThree=common->SixteenToTen(list[16]+" "+list[17]);
                    MainWindow::tempDataThree=tempThree.toDouble()/100;

                    QString tempFour=common->SixteenToTen(list[18]+" "+list[19]);
                    MainWindow::tempDataFour=tempFour.toDouble()/100;

                    QString tempFive=common->SixteenToTen(list[20]+" "+list[21]);
                    MainWindow::tempDataFive=tempFive.toDouble()/100;

                    QString tempSix=common->SixteenToTen(list[22]+" "+list[23]);
                    MainWindow::tempDataSix=tempSix.toDouble()/100;

                    MainWindow::tempOrder = list[25].toInt();
                }
                else
                {
                    if(list[list.length()-2]!="AA"&& list[list.length()-1]!="55"){
                        tempString.append(str+" ");
                    }
                    else
                    {
                        QSqlDatabase db = dbHelper::openConnection();
                        QSqlQuery query(db);

                        db.transaction();

                        if(list[list.length()-2]=="AA"&& list[list.length()-1]=="55" && tempString.isEmpty()){
                            tempString = str;
                        }else{
                            tempString.append(" "+str);
                        }
                        str=tempString;
                        tempString.clear();
                        QStringList list=str.split(" ");
                        for(int i=12;i<list.length()-4;i+=10){
                            if(i+4>list.length()||i+5>list.length()||i+6>list.length()||i+7>list.length()||
                                    i+8>list.length()||i+9>list.length()){
                                db.commit();
                                break;
                            }else
                            {
                                QString sql=QString("Insert into FluorescenceData values('','%1','%2','%3',"
                                                    "'%4','%5','%6','','','','')").arg(
                                            common->SixteenToTen(list[i]+" "+list[i+1]),
                                        common->SixteenToTen(list[11]),
                                        common->SixteenToTen(list[i+2]+" "+ list[i+3]),
                                        common->SixteenToTen(list[i+4]+" "+ list[i+5]),
                                        common->SixteenToTen(list[i+6]+" "+ list[i+7]),
                                        common->SixteenToTen(list[i+8]+" "+ list[i+9])
                                        );
                                query.exec(sql);
                            }
                        }

                        QString sql=QString("update FluorescenceData set SampleId=(select id from sampleInfo s "
                                            "where "
                                            "case "
                                            "when FluorescenceData.PositionNumber %1 = 0 "
                                            "then s.RowNum=7 and s.ColNum=FluorescenceData.PositionNumber/8-1 "
                                            "else "
                                            "s.RowNum = FluorescenceData.PositionNumber %1-1 and s.ColNum = FluorescenceData.PositionNumber/8 "
                                            "end)").arg("%8");
                        query.exec(sql);

                        sql="DELETE FROM FluorescenceData WHERE rowid NOT IN (SELECT MIN(rowid) FROM FluorescenceData GROUP BY positionNumber, CyclesNumber)";
                        query.exec(sql);
                        db.commit();

//                        MainWindow::canRefChart.set(0);
                    }
                }
            }
        }

        eqptinfo eqInfo;
        QString errStatus=eqInfo.errStatusRead();

        if(errStatus=="0"){
            // cnr 07发送 6.25
            QString Data=str.remove(QRegExp("\\s"));
            QString ty = Data.mid(4,4);
            QString wendubs = Data.mid(8,4);
            QString isright = Data.mid(12,4);
            QString isright2 = Data.mid(16,4);
            QString rw = Data.mid(50,2);
            if(ty=="003A"){
                QString gzfl = Data.mid(Data.length()-10,2);
                if (wendubs=="0018"&&rw=="07"&&Data.length()==60) {
                    if(rw=="07"){
                        order order1;
                        this->write(order1.toByteArray("6200","003A","000A","000100010007","1652","55AA"));
                    }
                }else if(gzfl=="07"){
                    allerror.clear();
                    int flnum=0;
                    for(int i=24;i<=Data.length()-14;i+=2){
                        QString gzdz = Data.mid(i,2);
                        QString gzdzv=mapGZ->value(gzdz);
                        allerror += gzdzv+";";
                    }
                    MainWindow::experimentStatus.set(3);
                    infochan.set(infochan.get()+1);
                    allerror.clear();
                }
            }
        }
    }, Qt::DirectConnection);

    //执行数据发送过程
    QObject::connect(this, &SerialportThread::SignalSendingData, this, [&](const QByteArray c_btaData){
        this->write(c_btaData);
    }, Qt::AutoConnection);
}

//跨线程转换
void SerialportThread::ClientConnectToHost(const QString & address, QString port)
{
    emit SignalConnectToHost(address, port);
}

//跨线程转换
void SerialportThread::ClientSendingData(const QByteArray & c_btaData)
{
    emit SignalSendingData(c_btaData);
}

void SerialportThread::serialclose(){
    if(this->isOpen())
    {
        this->close();
    }
}

bool SerialportThread::IsOnline(){
    return m_bOnLine;

}
